#include <iostream>
#include <assert.h>
#include "rapidjson/meta.h"
#include "rapidjson/serialize.hpp"
#include "rapidjson/deserialize.hpp"

struct TT {
	int a;
	short b;
	METAS(a, b);
	TT() = default;
	TT(int _a, short _b) : a(_a), b(_b) {}
};

struct Test {
	int a;
	short b;
	bool c;
	std::vector<int> d;
	TT e;
	std::unique_ptr<TT> f;
	std::shared_ptr<TT> g;
	METAS(a, b, c, d, e, f, g);
};

void test_ptr_is_null() {
	Test t = {100, 200, true, {1,2,3}, {10, 20}, nullptr, nullptr};
	std::cout << "begin" << std::endl;
	std::string json = rapidjson::serialize(t);
	std::cout << "end" << std::endl;
	std::cout << json << std::endl;

	Test other = {1, 2, false};
	bool result = rapidjson::deserialize(other, json);
	assert(result);
	assert(other.f == nullptr);
	assert(other.g == nullptr);
}

int main(void)
{
	test_ptr_is_null();
	Test t = {100, 200, true, {1,2,3}, {10, 20}, std::unique_ptr<TT>(new TT(100, 200)), std::make_shared<TT>(1000, 2000)};
	std::string json = rapidjson::serialize(t);
	std::cout << json << std::endl;

	Test other = {1, 2, false};
	bool result = rapidjson::deserialize(other, json);
	std::cout << result << std::endl;
	std::cout << other.a << std::endl;
	std::cout << other.b << std::endl;
	std::cout << other.c << std::endl;
	std::cout << other.d.size() << std::endl;
	std::cout << other.e.a << ", " << other.e.b << std::endl;
	std::cout << other.f->a << ", " << other.f->b << std::endl;
	std::cout << other.g->a << ", " << other.g->b << std::endl;
	return 0;
}
